package cn.zxh.improvement.common.core.utils;

import cn.zxh.improvement.common.core.function.FunctionExceptionUtil;
import io.vavr.control.Option;

/**
 * 反射工具类
 *
 * @author zxh
 * @since 2023-4-28 15:55:51
 */
@SuppressWarnings({"unchecked"})
public class Reflections {

    /**
     * 创建实例
     *
     * @param <T>             父类类型
     * @param clsName         类名称
     * @param superClass      父类
     * @return 实例
     */
    public static <T> Option<T> newInstance(String clsName, Class<T> superClass) {
        // function 自定义包裹异常，这里就不需要抛异常了
        return Reflections.<T>loadClass(clsName)
                .map(FunctionExceptionUtil.function((cs) -> cs.getDeclaredConstructor().newInstance()))
                .filter(inst -> requireInstanceOf(inst, superClass));
    }

    /**
     * 验证指定超类的实例
     *
     * @param inst       实例
     * @param superClass 父类
     * @return 如果实例是父类的实例或引发异常，则为true
     */
    public static <T> boolean requireInstanceOf(T inst, Class<T> superClass) {
        if (inst != null) {
            Assert.require(superClass.isInstance(inst));
        }
        return true;
    }

    /**
     * 加载类
     *
     * @param clsName 类名称
     * @return 包装类型
     */
    public static <T> Option<Class<T>> loadClass(String clsName) {
        // 异常包裹的 Supplier
        return Option.of(
                FunctionExceptionUtil
                        .supplier(() -> (Class<T>) Class.forName(clsName).getDeclaredConstructor().newInstance())
                        .get());
    }
}
